/* eslint-disable @typescript-eslint/no-explicit-any */
import { dom, Nodes } from '@knno/dom';
import { pickColorStyle } from './colorPicker.css';
import { AdaptivePopup } from '../adaptivePopup/adaptivePopup';
import { PopupPosition, Pos } from '../popup/popup';
import '../../dict';
import { DICT } from '../../dict';
import { vars } from '../global.css';

export type OpenSelectColorOptions = {
	refer?: Nodes;
	color?: string;
	useAction?: boolean;
	width?: string | number;
	popupPosition?: PopupPosition | Pos;
};

export interface SelectHandler {
	close(): void;
	onSelect(callback: SelectColorCallback): this;
	onClose(callback: () => void): this;
}

export type SelectColorCallback = (color: string) => void;

const COLOR_TABLE = [
	['FFFFFF', '000000', 'E7E6E6', 'FF0000', 'FF7F00', 'FFFF00', '00FF00', '00FFFF', '0000FF', '8B00FF'],
	['F1F1F1', '7F7F7F', 'CFCECE', 'FFCDCD', 'FFCCCD', 'FFFFCD', 'CDFFCD', 'CDFFFF', 'CDCDFF', 'D1CDFF'], // dark: 100%, light: 80%
	['D7D7D7', '595959', 'AEAAAA', 'FF9A9A', 'FFB29A', 'FFFF9A', '9AFF9A', '9AFFFF', '9A9AFF', 'B99AFF'], // dark: 100%, light: 60%
	['BEBEBE', '3F3F3F', '757070', 'FF6666', 'FF9966', 'FFFF66', '66FF66', '66FFFF', '6666FF', 'A266FF'], // dark: 100%, light: 40%
	['A4A4A4', '262626', '3A3737', 'C00000', 'C06000', 'C0C000', '00C000', '00C0C0', '0000C0', '6800C0'], // dark: 25%, light: 100%
	['7E7E7E', '0C0C0C', '171616', '800000', '804000', '808000', '008000', '008080', '000080', '460080'],
];

export class ColorPicker {
	static show({
		refer,
		useAction = false,
		width = '18em',
		popupPosition = 'bottom-left',
	}: OpenSelectColorOptions = {}): SelectHandler {
		let onClose: (() => void) | undefined;
		let onSelect: SelectColorCallback | undefined;
		const selectColor = (color: string) => {
			onSelect?.(color);
			pop.close();
			setTimeout(() => {
				refer?.focus();
			});
		};

		const defaultTd = dom.td().attr('colspan', '10').attr('tabIndex', '0').text(DICT.default);
		defaultTd.on('mousedown', function (evt) {
			evt.preventDefault();
			evt.stopImmediatePropagation();
			this.focus();
			selectColor('');
		});
		const container = dom
			.table(pickColorStyle)
			.on('mousedown', (evt) => {
				evt.preventDefault();
				evt.stopImmediatePropagation();
			})
			.append(
				dom.tr().append(defaultTd).css('marginBottom', '0.5em'),
				...new Array(6).fill(0).map((_, r) => {
					return dom.tr().append(
						...new Array(10).fill(0).map((_, c) => {
							const color = '#' + COLOR_TABLE[r][c];
							return dom
								.td()
								.on('mousedown', function (evt) {
									evt.preventDefault();
									evt.stopImmediatePropagation();
									this.focus();
									selectColor(color);
								})
								.attr('tabIndex', '0')
								.css({
									backgroundColor: color,
								});
						})
					);
				})
			);
		const pop = AdaptivePopup.show(container, {
			refer,
			popupPosition,
			focus: false,
			useAction,
			width,
			noActionBar: true,
		})
			.onOpen(() => {
				defaultTd.focus();
			})
			.onClose(() => {
				onClose?.();
			});
		return {
			close() {
				pop.close();
			},
			onSelect(callback) {
				onSelect = callback;
				return this;
			},
			onClose(callback) {
				onClose = callback;
				return this;
			},
		};
	}
}
